#ifndef __GETIMAGE_H__
#define __GETIMAGE_H__

// #include "usb_camera.h"
#include <iostream>
#include <QThread>
#include <fstream>
#include <cstring>
#include<QImageReader>
#include<QBuffer>
#include <QUdpSocket>
#include <QDebug>

#include <QCoreApplication>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

extern "C"
{
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <linux/types.h>          /* for videodev2.h */
    #include <linux/videodev2.h>
    #include <poll.h>
    #include <sys/mman.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <stdbool.h>
}

#define DES_TO_SAVE     "/mnt/hgfs/Share_file-2/licheePI_USB_Camera/"
#define TO_SAVE_NAME    "saved.yuv"

#define FILE_VIDEO "/dev/video0"
#define IMAGEWIDTH 640
#define IMAGEHEIGHT 480
// #define OUTPUTWIDTH 640
// #define OUTPUTHEIGHT 384
class GetImage : public QThread
{
    Q_OBJECT

public:
    explicit GetImage(QWidget *parent = nullptr);
    ~GetImage();
    bool init();
    void disinit();
    void run() override;
    int expectedTotalSize =  737280;
    int packet_size = 32760;
    // int packet_size = 36864;
    int start_flag = 1;
    int error_flag = 1;
    int cur_index = 0;
    int counter = 0;
#if 1
    QUdpSocket *udpSocket_recv;
    QUdpSocket *udpSocket_send;
    // QByteArray receivedData;  // 用于存储已接收的数据
    char* receivedData = NULL;  // 动态分配内存用于存放接收到的数据
    char * image_data = NULL;
    quint64 receivedDataSize;
    QHostAddress dstip;
    // quint16 dstport = 30300;
    quint16 dstport = 9999;
#else
    char * yuvImage;
    uint8_t* rgbData;
    uint8_t* change_rgbData;
    int outputWidth = 640;
    int outputHeight = 384;
#endif

signals:
    void sendReceiveImageToWidget(const QImage &image);

private slots:
    void receiveYolov5Image();

private:
#if 1
    QByteArray received_data;   //接受到的数据
    int packet_unit= 2048;
    void sendYolov5ImageToTargetHost(const QImage &image, int packet_unit);   //分包传输
    QImage convertBGRtoQImage(const uint8_t* bgrData, int width, int height);
    QImage BGRToRGB(const uint8_t* bgr, int width, int height);
#else
    int fd;
    struct v4l2_fmtdesc fmtdesc;
    struct v4l2_frmsizeenum fsenum;
    int fmt_index = 0;
    int frame_index = 0;
    int i;
    void *bufs[32];
    int buf_cnt;
    int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    struct pollfd fds[1];
    char filename[32];
    int file_cnt = 0;
    // 初始化摄像头
    int init_camera();
    // 关闭相机
    int close_v4l2(void);
    // 获取数据
    int grap_image();
    void YUYVToRGB(const uint8_t* yuyv, int width, int height, uint8_t* rgb);
    // 格式转换
    void yuyv2yuv420(char *inbuf,  char *outbuf);
    // 上下翻转 RGB 数据
    void FlipImageVertical(uint8_t* data, int width, int height);
    // 在 RGB 数据上绘制矩形框边缘
    void DrawRectangleOutline(uint8_t* data, int width, int height, int x, int y, int rectWidth, int rectHeight);
    // 在 RGB 数据上绘制矩形框
    void DrawRectangle(uint8_t* data, int width, int height, int x, int y, int rectWidth, int rectHeight);
    // 等比缩放 RGB 数据并补零
    void ScaleAndPadRGB(const uint8_t* input, int inputWidth, int inputHeight, uint8_t* output, int outputWidth, int outputHeight);
    // 保存 RGB 数据为 BMP 文件
    //void SaveRGBToBMP(const char* filename, const uint8_t* data, int width, int height);
    void SaveRGBToBMP(const std::string& filename, const uint8_t* data, int width, int height);
    // 定义 YUV 转 RGB 的函数
    void YUV420ToRGB(const uint8_t* yuv, int width, int height, uint8_t* rgb);
    uint8_t limitToRange(uint8_t value);
    int usb_camera_file_save( char * image);
#endif
};

#endif